/**
 * @file STL_RtspRequst.cpp
 * @author Derek Liu (yjkhtddx@sina.com)
 * @brief 
 * @version 0.1
 * @date 2021-02-19
 * 
 * @copyright Copyright Sci-Tech Laboratories (c) 2021
 * 
 */

#include "STL_RtspRequest.h"
#include "STL_Digest.h"

namespace STL
{
    STL_RtspRequest::STL_RtspRequest() : m_Digest(false)
    {
        m_method = "OPTIONS";
        m_uri = "rtsp://127.0.0.1/";
        m_version = "RTSP/1.0";
        m_headers["User-Agent"] = "STLRtspClient/0.0.1";
        m_body.clear();
    }

    void STL_RtspRequest::setMethod(std::string method)
    {
        //TODO 验证 DESCRIBE,SETUP,TEARDOWN,PLAY,PAUSE,OPTIONS,ANNOUNCE,RECORD...
        m_method = method;
    }
    void STL_RtspRequest::setUri(std::string uri)
    {
        m_uri = uri;
    }
    void STL_RtspRequest::setBody(std::string body)
    {
        m_body = body;
        // m_headers["Content-Length"] = std::to_string(m_body.size());
    }
    void STL_RtspRequest::setBodyFromJson(JSONCPP::Value body)
    {
        m_body = getFastString(body);
        m_headers["Content-Type"] = "application/json";
        // m_headers["Content-Length"] = std::to_string(m_body.size());
    }

    void STL_RtspRequest::setContentType(std::string type)
    {
        if (type.empty())
            return;
        // TODO 检验是否合法
        m_headers["Content-Type"] = type;
    }

    void STL_RtspRequest::setBodyFromFile(std::string filePath)
    {
        //TODO 文件发送时,需要边读取边发送
    }

    void STL_RtspRequest::addHeader(std::string header, std::string value)
    {
        if (value.empty())
            return;
        m_headers[header] = value;
    }

    void STL_RtspRequest::setCSeq(int cseq)
    {
        std::string s_cseq = std::to_string(cseq);
        addHeader("CSeq", s_cseq);
    }

    void STL_RtspRequest::addAuthorization(std::string value)
    {
        m_headers["Authorization"] = value;
    }
    void STL_RtspRequest::addBasicAuthorization(std::string username, std::string password, std::string realm)
    {
        m_headers["Authorization"] = STL_Digest::getMessageForBasicAuthenticate(username, password, realm);
        m_username = username;
        m_password = password;
    }

    void STL_RtspRequest::addDigestAuthorization(std::string username, std::string password, std::string realm, std::string nonce, std::string qop /* = ""*/, std::string algorithm /* = ""*/, std::string opaque /* = ""*/)
    {
        //TODO 目前只处理 qop=="" algorithm!=md5-sess时
        m_Digest = true;
        m_username = username;
        m_password = password;
        m_realm = realm;
        m_nonce = nonce;
        m_qop = qop;
        m_algorithm = algorithm;
        m_opaque = opaque;
    }

    std::string STL_RtspRequest::genRequstMessage()
    {
        std::string ret = std::string("");
        ret = ret + m_method + " " + m_uri + " " + m_version + "\r\n";
        if (m_body.empty())
        {
            m_headers.erase("Content-Type");
        }

        if (m_Digest)
        {
            //TODO 缺两个参数，优化时处理
            addAuthorization(STL_Digest::getMessageForAuthenticate(m_username, m_password, m_method, m_uri, m_body, m_realm, m_nonce, 0, m_algorithm, "", m_qop, m_opaque));
        }

        m_headers["Content-Length"] = std::to_string(m_body.size());

        for (std::map<std::string, std::string>::iterator it = m_headers.begin(); it != m_headers.end(); it++)
        {
            ret = ret + it->first + ": " + it->second + "\r\n";
        }

        ret = ret + "\r\n" + m_body;
        return ret;
    };
}